Ocaml 爆速入門
OCaml爆速入門
レコード
code:ocaml
# type point = {x: int; y: int};;
type point = { x : int; y : int; }
# let origin = {x = 0; y = 0};;
val origin : point = {x = 0; y = 0}
(* ドット記法で値を取り出す *)
# origin.x;;
- : int = 0
# origin.y;;
- : int = 0
(* パターンマッチで値を取り出す *)
# let {x = ox; y = oy } = origin;;
val ox : int = 0
val oy : int = 0
# ox;;
- : int = 0
# oy;;
- : int = 0
# let middle p1 p2 =
{x = (p1.x + p2.x) / 2; y = (p1.y + p2.y) / 2}
;;
val middle : point -> point -> point = <fun>
# middle {x = 10; y = 20} {x = 20; y = 30};;
- : point = {x = 15; y = 25}
ヴァリアントの練習
code:ocaml
# type furikake = Shake | Katsuo | Nori;;
type furikake = Shake | Katsuo | Nori
furikake
ふりかけのデータ型
型 furikake の要素は Shake, Katsuo, Nori の3つ
Shake, Katsuo, Nori はコンストラクタと呼ばれ、大文字で始める必要がある
code:ocaml
# let isVeggie f =
match f with
Shake -> false
| Katsuo -> false
| Nori -> true
;;
# isVeggie Shake;;
- : bool = false
# isVeggie Nori;;
- : bool = true
code:ocaml
# type furikake = Shake | Katsuo | Nori;;
type furikake = Shake | Katsuo | Nori
# type miso = Aka | Shiro | Awase;;
type miso = Aka | Shiro | Awase
# type gu = Wakame | Tofu | Radish;;
type gu = Wakame | Tofu | Radish
# type dish = PorkCutlet | Soup of {m: miso; g: gu} | Rice of furikake;;
type dish = PorkCutlet | Soup of { m : miso; g : gu; } | Rice of furikake
# PorkCutlet;;
- : dish = PorkCutlet
# Soup {m = Aka; g = Tofu};;
- : dish = Soup {m = Aka; g = Tofu}
# Rice Shake;;
- : dish = Rice Shake
# let isSolid d =
match d with
PorkCutlet -> true
| Soup m_and_g -> false
| Rice f -> true
;;
val isSolid : dish -> bool = <fun>
# isSolid PorkCutlet;;
- : bool = true
# isSolid (Soup {m = Shiro; g = Tofu});;
- : bool = false
# isSolid (Rice Shake);;
- : bool = true
料理の値段を計算
とんかつ 350円
味噌汁 90円
ふりかけご飯
シャケ、カツオ 90円
ノリ 80円
code:ocaml
# let priceOfDish d =
match d with
PorkCutlet -> 350
| Soup _ -> 90
| Rice Nori -> 80
| Rice (Shake | Katsuo) -> 90
;;
val priceOfDish : dish -> int = <fun>
# priceOfDish PorkCutlet;;
- : int = 350
# priceOfDish (Soup {m = Awase; g = Tofu});;
- : int = 90
# priceOfDish (Rice Shake);;
- : int = 90
# priceOfDish (Rice Nori);;
- : int = 80
再帰ヴァリアントの練習として定食型(menu型)を作る。
code:ocaml
# type menu = Smile | Add of {d: dish; next: menu};;
type menu = Smile | Add of { d : dish; next : menu; }
(* 注文なし *)
# let m1 = Smile;;
val m1 : menu = Smile
(* トンカツのみ *)
# let m2 = Add {d = PorkCutlet; next = Smile};;
val m2 : menu = Add {d = PorkCutlet; next = Smile}
(* ノリふりかけごはん追加 *)
# let m3 = Add {d = Rice Nori; next = m2};;
val m3 : menu =
Add {d = Rice Nori; next = Add {d = PorkCutlet; next = Smile}}
(* シャケふりかけごはんおかわり *)
# let m4 = Add {d = Rice Shake; next = m3};;
val m4 : menu =
Add
{d = Rice Shake;
next = Add {d = Rice Nori; next = Add {d = PorkCutlet; next = Smile}}}
値段を計算する
code:ocaml
# let rec priceOfMenu m =
match m with
Smile -> 0
| Add { d = d1; next = m' } -> (priceOfDish d1) + (priceOfMenu m')
;;
val priceOfMenu : menu -> int = <fun>
# priceOfMenu m1;;
- : int = 0
# priceOfMenu m2;;
- : int = 350
# priceOfMenu m3;;
- : int = 430
# priceOfMenu m4;;
- : int = 520
(m' のシングルクォートはなんだんだろう?)
変更可能データ構造
code:ocaml